package handler

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"math/rand"
	"net/http"
	"path"
	"strings"
	"time"
	"video_-chat/api/request"
	"video_-chat/global"
	"video_-chat/internal/moble"
	"video_-chat/pkg"
)

func Sms(context *gin.Context) {
	var sms request.Sms
	if err := context.ShouldBind(&sms); err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100201, //100000以上自定义，成功为200，解析失败为100201
			"msg":  err.Error(),
		})
		return
	}
	ok, _ := path.Match("^13*{10}$", sms.Phone)
	if ok {
		context.JSON(http.StatusOK, gin.H{
			"code": 100204,
			"msg":  "手机号格式错误",
		})
		return
	}
	key := fmt.Sprintf("sms:%s", sms.Phone)
	count, _ := global.RDB.Get(global.Ctx, key+"count").Result()
	if count != "" {
		context.JSON(http.StatusOK, gin.H{
			"code": 100203,
			"msg":  "操作频繁，请稍后再试",
		})
		return
	}
	capt := fmt.Sprintf("%d", rand.Intn(9000)+1000)
	var alisms pkg.AliSmsCaptcha
	alisms.Capt = capt
	alisms.Phone = sms.Phone
	captcha, err := alisms.SmsCaptcha()
	if err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100202,
			"msg":  err.Error(),
			"data": captcha,
		})
		return
	}

	global.RDB.Set(global.Ctx, key+"count", "ok", 1*time.Minute)
	global.RDB.Set(global.Ctx, key, capt, 5*time.Minute)
	context.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "短信发送成功，请注意接收",
	})
	return
}
func Login(context *gin.Context) {
	var login request.Login
	if err := context.ShouldBind(&login); err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100201, //100000以上自定义，成功为200，解析失败为100201
			"msg":  err.Error(),
		})
		return
	}
	key := fmt.Sprintf("sms:%s", login.Phone)
	capt, _ := global.RDB.Get(global.Ctx, key).Result()
	if capt != login.Captcha {
		context.JSON(http.StatusOK, gin.H{
			"code": 100202,
			"msg":  "验证码错误",
		})
		return
	}
	var User moble.Users
	User.Phone = login.Phone
	loginDB := global.DB.Begin()
	if err := loginDB.Where("phone = ?", login.Phone).Find(&User).Error; err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100203,
			"msg":  err.Error(),
		})
		loginDB.Rollback()
		return
	}
	User.LostLoginTime = time.Now()
	if err := loginDB.Where("user_id = ?", User.UserId).Updates(&User).Error; err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100204,
			"msg":  err.Error(),
		})
		loginDB.Rollback()
		return
	}
	loginDB.Commit()
	set, _ := json.Marshal(&User)
	handler, err := pkg.TokenHandler(string(set))
	if err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100204,
			"msg":  err.Error,
		})
		return
	}

	global.RDB.Set(global.Ctx, handler, set, 2*time.Hour)

	global.RDB.HSet(global.Ctx, "login_once", fmt.Sprintln(User.UserId), "ok")

	context.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "登陆成功",
		"data": handler,
	})
}

func UserData(context *gin.Context) {
	var user moble.Users
	context.Request.ParseForm()
	us := context.Request.Form.Get("user")
	json.Unmarshal([]byte(us), &user)
	key := fmt.Sprintf("user:%d:body", user.UserId)
	var data = struct {
		User              moble.Users
		VideoCount        int64
		CommentLikedCount int64
		FollowerCount     int64
		FollowedCount     int64
	}{
		user,
		0,
		0,
		0,
		0,
	}
	datas, _ := global.RDB.Get(global.Ctx, key).Result()
	if datas != "" {
		json.Unmarshal([]byte(datas), &data)
	} else {
		set, _ := json.Marshal(&data)
		global.RDB.Set(global.Ctx, key, set, 0)
	}
	var video_count, comment_liked_count, follower_count, followed_count int64
	global.DB.Model(&moble.Video{}).Where("user_id = ?", user.UserId).Pluck("count(*)", &video_count)
	global.DB.Model(&moble.Follows{}).Where("follower_id = ?", user.UserId).Pluck("count(*)", &follower_count)
	global.DB.Model(&moble.Follows{}).Where("followed_id = ?", user.UserId).Pluck("count(*)", &followed_count)
	global.DB.Model(&moble.Comments{}).Where("user_id = ?", user.UserId).Pluck("sum(comments.like_count)", &comment_liked_count)
	data.VideoCount = video_count
	data.CommentLikedCount = comment_liked_count
	data.FollowerCount = follower_count
	data.FollowedCount = followed_count
	context.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "个人主页查询成功",
		"data": data,
	})
}

func UserFollow(context *gin.Context) {
	var user moble.Users
	context.Request.ParseForm()
	us := context.Request.Form.Get("user")
	json.Unmarshal([]byte(us), &user)
	var user_follow request.UserFollow
	if err := context.ShouldBind(&user_follow); err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100201,
			"msg":  err.Error(),
		})
		return
	}
	var follow moble.Follows
	if err := global.DB.Where("follower_id = ? and followed_id = ?", user.UserId, user_follow.SeedId).Find(&follow).Error; err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100202,
			"msg":  err.Error(),
		})
		return
	}
	var msg string
	if follow.Status == 0 {
		follow.Status = 1
		follow.FollowerId = user.UserId
		follow.FollowedId = int32(user_follow.SeedId)
		follow.FollowTime = time.Now()
		global.DB.Create(&follow)
		msg = "关注成功"
	} else {
		global.DB.Where("follow_id = ?", follow.FollowId).Delete(&moble.Follows{})
		msg = "取消关注成功"
	}
	context.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  msg,
	})
	rab := pkg.NewRabbitMQSimple(fmt.Sprintf("user:%d", user_follow.SeedId))
	var message moble.Message
	message = moble.Message{
		ReceiverId: int32(user_follow.SeedId),
		SenderId:   user.UserId,
		Type:       0,
		Content:    fmt.Sprintf("用户：%s,关注了您", user.Nickname),
		SendTime:   time.Now(),
		IsRead:     0,
	}
	global.DB.Create(&message)
	set, _ := json.Marshal(message)
	rab.PublishSimple(string(set))
}

func UserHandImageUpdate(context *gin.Context) {
	var user moble.Users
	context.Request.ParseForm()
	us := context.Request.Form.Get("user")
	json.Unmarshal([]byte(us), &user)
	key := fmt.Sprintf("user:%d:body", user.UserId)
	var data = struct {
		User              moble.Users
		VideoCount        int64
		CommentLikedCount int64
		FollowerCount     int64
		FollowedCount     int64
	}{
		user,
		0,
		0,
		0,
		0,
	}
	datas, _ := global.RDB.Get(global.Ctx, key).Result()
	json.Unmarshal([]byte(datas), &data)
	file, m, _ := context.Request.FormFile("image")
	if !strings.Contains(".png.jpg.jpge", path.Ext(m.Filename)) {
		context.JSON(http.StatusOK, gin.H{
			"code": 100201,
			"msg":  "格式错误",
		})
	}
	upload, err := pkg.Upload(file, m)
	if err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code": 100202,
			"msg":  err.Error(),
		})
		return
	}
	user.AvatarUrl = upload
	global.DB.Updates(&user)
	data.User.AvatarUrl = upload
	global.RDB.Set(global.Ctx, key, data, 0)
	context.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "头像替换成功",
		"data": upload,
	})
}
